package pe.gob.servir.apps.censodirectivo.ejb.dao;

import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import javax.ejb.EJB;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

import oracle.jdbc.OracleTypes;

import org.apache.log4j.Logger;
import org.hibernate.Session;
import org.hibernate.jdbc.Work;

import pe.gob.servir.apps.censodirectivo.common.constantes.Constantes;
import pe.gob.servir.apps.censodirectivo.common.dao.AbstractJPABaseDAO;
import pe.gob.servir.apps.censodirectivo.common.util.Utilitario;
import pe.gob.servir.apps.censodirectivo.excepcion.DAOExcepcion;
import pe.gob.servir.apps.censodirectivo.model.bean.Censo;
import pe.gob.servir.apps.censodirectivo.model.bean.MensajeRespuesta;
import pe.gob.servir.apps.censodirectivo.model.bean.OpcionUsuario;
import pe.gob.servir.apps.censodirectivo.model.bean.Usuario;
import pe.gob.servir.apps.censodirectivo.persistence.entity.TblUsuario;

/**
 * Session Bean implementation class UsuarioDAO
 */
@Stateless
public class UsuarioDAO extends AbstractJPABaseDAO<TblUsuario> implements UsuarioDAOLocal {

	private static final Logger log = Logger.getLogger(UsuarioDAO.class);

	@EJB
	private ConsumirProcedimientoDAOLocal consumirProcedimientoDAOLocal;
	
	@PersistenceContext(unitName = "persistenceUnitCenso")
	EntityManager entityManager;

	public UsuarioDAO() {
		super(TblUsuario.class);
	}

	@Override
	protected EntityManager getEntityManager() {
		return entityManager;
	}

	@Override
	public void actualizarClave(String usuario, String nuevaClave) throws DAOExcepcion {
		try {

			final String JPQL = "UPDATE TblUsuario u "
							  + "SET u.clave = :clave, u.primeraVez = :primeraVez "
							  + "WHERE u.usuario = :usuario";
			Query query = this.entityManager.createQuery(JPQL);
			query.setParameter("usuario", usuario);
			query.setParameter("clave", nuevaClave);
			query.setParameter("primeraVez", "N");
			query.executeUpdate();
			log.info("Se actualizo clave con exito");
		} catch (Exception e) {
			log.error("ERROR: ", e);
			String mensajeError = consumirProcedimientoDAOLocal.consultarMensaje(Constantes.CODIGO_MSJ_ERROR_DB);
			throw new DAOExcepcion(Constantes.CODIGO_MSJ_ERROR_DB, mensajeError);
		}
		
	}
	
	@Override
	public List<Usuario> validarUsuario(final String usuario) throws DAOExcepcion {

		Session session = entityManager.unwrap(Session.class);
		final List<Usuario> listaUsuariosResponse = new ArrayList<Usuario>();
		
		try {
			session.doWork(new Work() {
	
				@Override
				public void execute(Connection connection) throws SQLException {
					CallableStatement callableStatement = null;
					ResultSet resultset = null;
	
					try {
						callableStatement = connection.prepareCall(Constantes.SP_VALIDAR_USUARIO);
						callableStatement.setString(1, usuario);
						callableStatement.registerOutParameter(2, OracleTypes.CURSOR);
						callableStatement.registerOutParameter(3, OracleTypes.INTEGER);
						callableStatement.registerOutParameter(4, OracleTypes.VARCHAR);
						callableStatement.execute();
						log.info("Se ejecuto exitosamente el SP.");
						log.info("Parametros Salida [idError]: " + callableStatement.getInt(3));
						log.info("Parametros Salida [desError]: " + callableStatement.getInt(4));
						resultset = (ResultSet) callableStatement.getObject(2);//Cursor
						while (resultset.next()) {
							Usuario usuario = new Usuario();
							Censo censo = new Censo();
							usuario.setUsuarioId(resultset.getLong("USUARIO_ID"));
							usuario.setUsuario(resultset.getString("USUARIO"));
							usuario.setClave(resultset.getString("CLAVE"));
							usuario.setPrimeraVez(resultset.getString("PRIMERA_VEZ"));
							usuario.setPerfil(resultset.getString("PERFIL"));
							usuario.setIdEntidad(resultset.getLong("ENTIDAD_ID"));
							usuario.setNombEntidad(resultset.getString("NOMB_ENTIDAD"));
							usuario.setNombres(resultset.getString("NOMBRE_COMPLETO"));
							usuario.setPersonaId(resultset.getLong("PERSONA_ID"));
							usuario.setPerfilId(resultset.getLong("PERFIL_ID"));
							usuario.setFechaInicioHabilitacion(resultset.getDate("FECHA_INICIO_HABILITACION"));
							usuario.setFechaFinHabilitacion(resultset.getDate("FECHA_FIN_HABILITACION"));
							usuario.setFechaInicioRegistro(resultset.getDate("FECHA_INICIO_REGISTRO"));
							usuario.setFechaFinRegistro(resultset.getDate("FECHA_FIN_REGISTRO"));
							usuario.setEstadoRegistro(resultset.getString("ESTADO_REGISTRO"));
							usuario.setResponsableId(resultset.getLong("RESPONSABLE_ID"));
							usuario.setDirectivoId(resultset.getLong("DIRECTIVO_PUBLICO_ID"));
							censo.setCensoId(resultset.getLong("CENSO_ID"));
							usuario.setCenso(censo);
							listaUsuariosResponse.add(usuario);
						}
						
					} catch(SQLException e){
						log.error("SQLException : ", e);
						throw e;
					} catch (Exception e) {
						log.error("Exception : ", e);
						throw e; 
					} finally {
						Utilitario.cerrarConexiones(resultset, callableStatement);
					}
				}
	
			});
		} catch (Exception e) {
			String mensajeError = consumirProcedimientoDAOLocal.consultarMensaje(Constantes.CODIGO_MSJ_ERROR_DB);
			throw new DAOExcepcion(Constantes.CODIGO_MSJ_ERROR_DB, mensajeError);
		}
		return listaUsuariosResponse;
	}
	
	@Override
	public List<OpcionUsuario> listaOpcionesUsuario(final String usuario) throws DAOExcepcion {

		Session session = entityManager.unwrap(Session.class);
		final List<OpcionUsuario> listaUsuariosResponse = new ArrayList<OpcionUsuario>();
		try {
			session.doWork(new Work() {
	
				public void execute(Connection connection) throws SQLException {
					CallableStatement callableStatement = null;
					ResultSet resultset = null;
	
					try {
	
						callableStatement = connection.prepareCall(Constantes.SP_CONSULTAR_OPCION_USUARIO);
						callableStatement.setString("E_USUARIO", usuario);
						callableStatement.registerOutParameter("S_CURSOR", OracleTypes.CURSOR);
						callableStatement.registerOutParameter("S_ID_ERROR", OracleTypes.INTEGER);
						callableStatement.registerOutParameter("S_DES_ERROR", OracleTypes.VARCHAR);
						callableStatement.execute();
						log.info("Se ejecuto exitosamente el SP.");
						log.info("Parametros Salida [idError]: " + callableStatement.getInt("S_ID_ERROR"));
						log.info("Parametros Salida [desError]: " + callableStatement.getInt("S_DES_ERROR"));
	
						resultset = (ResultSet) callableStatement.getObject("S_CURSOR");//Cursor
						while (resultset.next()) {
							OpcionUsuario opcionUsuario = new OpcionUsuario();
							opcionUsuario.setUsuario_id(resultset.getLong("USUARIO_ID"));
							opcionUsuario.setUsuario(resultset.getString("USUARIO"));
							opcionUsuario.setOpcion_id(resultset.getLong("OPCION_ID"));
							opcionUsuario.setOpcion(resultset.getString("OPCION"));
							opcionUsuario.setUrl(resultset.getString("URL"));
							opcionUsuario.setIcono(resultset.getString("ICONO"));
							opcionUsuario.setOrden(resultset.getLong("ORDEN"));
							opcionUsuario.setOpcion_id_padre(resultset.getLong("OPCION_ID_PADRE"));
							opcionUsuario.setInsertar(resultset.getString("INSERTAR"));
							opcionUsuario.setEditar(resultset.getString("EDITAR"));
							opcionUsuario.setConsultar(resultset.getString("CONSULTAR"));
							opcionUsuario.setEliminar(resultset.getString("ELIMINAR"));
							listaUsuariosResponse.add(opcionUsuario);
						}
					} catch(SQLException e){
						log.error("SQLException : ", e);
						throw e;
					} catch (Exception e) {
						log.error("Exception : ", e);
						throw e; 
					} finally {
						Utilitario.cerrarConexiones(resultset, callableStatement);
					}
				}
	
			});
		} catch (Exception e) {
			String mensajeError = consumirProcedimientoDAOLocal.consultarMensaje(Constantes.CODIGO_MSJ_ERROR_DB);
			throw new DAOExcepcion(Constantes.CODIGO_MSJ_ERROR_DB, mensajeError);
		}
		return listaUsuariosResponse;
	}
	
	@Override
	public List<Usuario> filtrarListaUsuarios(final String dni, final String usuario,
			final String apellidoPaterno, final String apellidoMaterno,
			final String nombres, final String entidad, final String perfil,
			final String estado) throws DAOExcepcion {

		Session session = entityManager.unwrap(Session.class);
		final List<Usuario> listaUsuariosResponse = new ArrayList<Usuario>();
		try {
	
			session.doWork(new Work() {
	
				@Override
				public void execute(Connection connection) throws SQLException {
					CallableStatement callableStatement = null;
					ResultSet resultset = null;
	
					try {
						callableStatement = connection.prepareCall(Constantes.SP_BUSQUEDA_USUARIO);
						callableStatement.setString("X_DNI", dni);
						callableStatement.setString("X_APE_PATERNO", apellidoPaterno);
						callableStatement.setString("X_APE_MATERNO", apellidoMaterno);
						callableStatement.setString("X_NOMBRES", nombres);
						callableStatement.setString("X_ENTIDAD_ID", entidad);
						callableStatement.setString("X_ID_PERFIL", perfil);
						callableStatement.setString("X_ID_ESTADO", estado);
						callableStatement.setString("X_USUARIO", usuario);
						callableStatement.registerOutParameter("X_CURSOR", OracleTypes.CURSOR);
						callableStatement.registerOutParameter("X_ID_ERROR", OracleTypes.INTEGER);
						callableStatement.registerOutParameter("X_DES_ERROR", OracleTypes.VARCHAR);
						callableStatement.execute();
						
						log.info("Se ejecuto exitosamente el SP.");
						log.info("Parametros Salida [idError]: " + callableStatement.getInt("X_ID_ERROR"));
						log.info("Parametros Salida [desError]: " + callableStatement.getInt("X_DES_ERROR"));
	
						resultset = (ResultSet) callableStatement.getObject("X_CURSOR");//Cursor
						while (resultset.next()) {
							Usuario usuario = new Usuario();
							usuario.setUsuarioId(resultset.getLong("USUARIO_ID"));
							usuario.setPersonaId(resultset.getLong("PERSONA_ID"));
							usuario.setDni(resultset.getString("NRO_DOCUMENTO"));
							usuario.setNombres(resultset.getString("NOMBRES"));
							usuario.setApellidoPaterno(resultset.getString("AP_PATERNO"));
							usuario.setApellidoMaterno(resultset.getString("AP_MATERNO"));
							usuario.setApellidoCasado(resultset.getString("AP_CASADA"));
							usuario.setPerfilId(resultset.getLong("PERFIL_ID"));
							usuario.setPerfil(resultset.getString("PERFIL"));
							usuario.setIdEntidad(resultset.getLong("ENTIDAD_ID"));
							usuario.setNombEntidad(resultset.getString("NOMB_ENTIDAD"));
							usuario.setNombreEstado(resultset.getString("ESTADO_REGISTRO"));
							usuario.setEstadoRegistro(resultset.getString("CODIGO_ESTADO"));
							if (resultset.getDate("FECHA_CREACION") != null) {
								usuario.setFechaCreacion(Utilitario.convertDateToString(resultset.getDate("FECHA_CREACION"), Constantes.FORMATO_FECHA_HORA));
							}
							usuario.setUsuarioCreador(resultset.getString("USUARIO_CREADOR"));
							usuario.setSexo(resultset.getString("sexo"));
							usuario.setDesEstadoCivil(resultset.getString("DES_ESTADO_CIVIL"));
							if (resultset.getDate("FECHA_NACIMIENTO") != null) {
								usuario.setFechaNacimiento(resultset.getDate("FECHA_NACIMIENTO"));	
							}
							usuario.setDireccion(resultset.getString("DIRECCION"));
							usuario.setUsuario(resultset.getString("USUARIO"));
							listaUsuariosResponse.add(usuario);
						}
	
					} catch(SQLException e){
						log.error("SQLException : ", e);
						throw e;
					} catch (Exception e) {
						log.error("Exception : ", e);
						throw e; 
					} finally {
						Utilitario.cerrarConexiones(resultset, callableStatement);
					}
				}
	
			});
		} catch (Exception e) {
			String mensajeError = consumirProcedimientoDAOLocal.consultarMensaje(Constantes.CODIGO_MSJ_ERROR_DB);
			throw new DAOExcepcion(Constantes.CODIGO_MSJ_ERROR_DB, mensajeError);
		}
		return listaUsuariosResponse;
	}

	
	@Override
	public MensajeRespuesta insertarUsuario(final long usuarioId, final String usuario,final long personaId, final long perfilId,
			final String usuarioCreador,final String estadoRegistro,final String clave, final String email) throws DAOExcepcion {
		Session session = entityManager.unwrap(Session.class);
		final MensajeRespuesta mensajeRespuesta = new MensajeRespuesta();
		try {
			session.doWork(new Work() {
				@Override
				public void execute(Connection connection) throws SQLException {
					CallableStatement callableStatement = null;
					ResultSet resultset = null;
					try {
						connection.setAutoCommit(false);
						callableStatement = connection.prepareCall(Constantes.SP_INSERTA_USUARIO);
						callableStatement.setString("E_USUARIO", usuario);
						callableStatement.setString("E_PERSONA_ID", String.valueOf(personaId));
						callableStatement.setString("E_USUARIO_CREADOR", usuarioCreador);
						callableStatement.setString("E_ESTADO_REGISTRO", estadoRegistro);
						callableStatement.setString("E_CLAVE", clave);
						callableStatement.setString("E_PERFIL_ID", String.valueOf(perfilId));
						callableStatement.setString("E_MAIL", email);
						callableStatement.registerOutParameter("S_USUARIO_ID", OracleTypes.NUMBER);
						callableStatement.registerOutParameter("S_ID_ERROR", OracleTypes.INTEGER);
						callableStatement.registerOutParameter("S_DES_ERROR", OracleTypes.VARCHAR);
						callableStatement.registerOutParameter("S_DES_ERROR_INFO", OracleTypes.VARCHAR);
						callableStatement.setLong("S_USUARIO_ID", usuarioId);
						callableStatement.execute();
						
						log.info("Se ejecuto exitosamente el SP.");

						int codigoError = callableStatement.getInt("S_ID_ERROR");
						String mensajeError = callableStatement.getString("S_DES_ERROR");
						String mensajeErrorInfo = callableStatement.getString("S_DES_ERROR_INFO");
						long idUsuario  = callableStatement.getInt("S_USUARIO_ID");
						mensajeRespuesta.setCodigoError(String.valueOf(codigoError));
						mensajeRespuesta.setMensajeError(mensajeError);
						mensajeRespuesta.setObjeto(idUsuario);
						mensajeRespuesta.setMensajeInfo(mensajeErrorInfo);
						
						if(codigoError == 0) {
							log.info("Se registro datos con exito en BD.");
							connection.commit();
						} else {
							log.info("No se pudo registrar los datos en BD. " + mensajeErrorInfo);
							throw new SQLException();
						}
					} catch(SQLException e){
						if (mensajeRespuesta.getMensajeInfo() != null){
							log.error("SQLException : " + mensajeRespuesta.getMensajeInfo());
						}
						connection.rollback();
						throw e;
					} catch (Exception e) {
						log.error("Exception : " + e.getMessage() , e);
						connection.rollback();
						throw e;
					} finally {
						Utilitario.cerrarConexiones(resultset, callableStatement);
					}
				}
			});
		} catch (Exception e) {
			if (mensajeRespuesta.getCodigoError() == null) {
				String mensajeError = consumirProcedimientoDAOLocal.consultarMensaje(Constantes.CODIGO_MSJ_ERROR_DB);
				throw new DAOExcepcion(Constantes.CODIGO_MSJ_ERROR_DB, mensajeError);
			}
			throw new DAOExcepcion(mensajeRespuesta.getCodigoError(), mensajeRespuesta.getMensajeError());
		}
		return mensajeRespuesta;
	}
	
	@Override
	public Usuario obtenerUsuarioPorId(final long usuarioId) throws DAOExcepcion {
		Session session = entityManager.unwrap(Session.class);
		final Usuario usuario = new Usuario();
		try {
			session.doWork(new Work() {
				@Override
				public void execute(Connection connection) throws SQLException {
					ResultSet resultset = null;
					PreparedStatement preparedStatement = null;
					String sql = "SELECT * FROM VW_CONSULTA_USUARIOS WHERE USUARIO_ID = ?";
					try {
						preparedStatement = connection.prepareStatement(sql);
						preparedStatement.setLong(1, usuarioId);
						resultset =	preparedStatement.executeQuery();
						log.info("Se ejecuto consulta con exito.");
						while (resultset.next()) {
							usuario.setUsuarioId(resultset.getLong("USUARIO_ID"));
							usuario.setPersonaId(resultset.getLong("PERSONA_ID"));
							usuario.setClave(resultset.getString("CLAVE"));
							usuario.setFechaCreacion(resultset.getString("FECHA_CREACION"));
							usuario.setUsuarioCreador(resultset.getString("USUARIO_CREADOR"));
							usuario.setUsuario(resultset.getString("USUARIO"));
							usuario.setDni(resultset.getString("NRO_DOCUMENTO"));
							usuario.setNombres(resultset.getString("NOMBRES"));
							usuario.setApellidoPaterno(resultset.getString("AP_PATERNO"));
							usuario.setApellidoMaterno(resultset.getString("AP_MATERNO"));
							usuario.setEstadoRegistro(resultset.getString("ESTADO_REGISTRO"));
							usuario.setPerfilId(resultset.getLong("PERFIL_ID"));
							usuario.setIdEntidad(resultset.getLong("ENTIDAD_ID"));
							usuario.setEmail(resultset.getString("EMAIL_PERSONAL"));
						}
					} catch(SQLException e) {
						log.error("SQLException : " , e);
						throw e;
					} catch (Exception e) {
						log.error("Exception : " , e);
						throw e;
					} finally {
						Utilitario.cerrarResultset(resultset);
						Utilitario.cerrarPreparedStatement(preparedStatement);
					}
				}
			});
		} catch (Exception e) {
			String mensajeError = consumirProcedimientoDAOLocal.consultarMensaje(Constantes.CODIGO_MSJ_ERROR_DB);
			throw new DAOExcepcion(Constantes.CODIGO_MSJ_ERROR_DB, mensajeError);
		}
		return usuario;
	}
	
	@Override
	public Usuario obtenerUsuarioPorLogin(final String sUsuario) throws DAOExcepcion {
		Session session = entityManager.unwrap(Session.class);
		final Usuario usuario = new Usuario();
		try {
			session.doWork(new Work() {
				@Override
				public void execute(Connection connection) throws SQLException {
					ResultSet resultset = null;
					PreparedStatement preparedStatement = null;
					String sql = "SELECT * FROM VW_CONSULTA_USUARIOS WHERE USUARIO = ?";
					try {
						preparedStatement = connection.prepareStatement(sql);
						preparedStatement.setString(1, sUsuario);
						resultset =	preparedStatement.executeQuery();
						log.info("Se ejecuto consulta con exito.");
						while (resultset.next()) {
							usuario.setUsuarioId(resultset.getLong("USUARIO_ID"));
							usuario.setPersonaId(resultset.getLong("PERSONA_ID"));
							usuario.setClave(resultset.getString("CLAVE"));
							usuario.setFechaCreacion(resultset.getString("FECHA_CREACION"));
							usuario.setUsuarioCreador(resultset.getString("USUARIO_CREADOR"));
							usuario.setUsuario(resultset.getString("USUARIO"));
							usuario.setDni(resultset.getString("NRO_DOCUMENTO"));
							usuario.setNombres(resultset.getString("NOMBRES"));
							usuario.setApellidoPaterno(resultset.getString("AP_PATERNO"));
							usuario.setApellidoMaterno(resultset.getString("AP_MATERNO"));
							usuario.setEstadoRegistro(resultset.getString("ESTADO_REGISTRO"));
							usuario.setPerfilId(resultset.getLong("PERFIL_ID"));
							usuario.setIdEntidad(resultset.getLong("ENTIDAD_ID"));
							usuario.setEmail(resultset.getString("EMAIL_PERSONAL"));
						}
					} catch(SQLException e) {
						log.error("SQLException : " , e);
						throw e;
					} catch (Exception e) {
						log.error("Exception : " , e);
						throw e;
					} finally {
						Utilitario.cerrarResultset(resultset);
						Utilitario.cerrarPreparedStatement(preparedStatement);
					}
				}
			});
		} catch (Exception e) {
			String mensajeError = consumirProcedimientoDAOLocal.consultarMensaje(Constantes.CODIGO_MSJ_ERROR_DB);
			throw new DAOExcepcion(Constantes.CODIGO_MSJ_ERROR_DB, mensajeError);
		}
		return usuario;
	}
	
	@Override
	public Usuario obtenerUsuarioPorEmail(final String email) throws DAOExcepcion {
		Session session = entityManager.unwrap(Session.class);
		final Usuario usuario = new Usuario();
		try {
			session.doWork(new Work() {
				@Override
				public void execute(Connection connection) throws SQLException {
					ResultSet resultset = null;
					PreparedStatement preparedStatement = null;
					String sql = "SELECT * FROM VW_CONSULTA_USUARIOS WHERE EMAIL_PERSONAL = ?";
					try {
						preparedStatement = connection.prepareStatement(sql);
						preparedStatement.setString(1, email);
						resultset =	preparedStatement.executeQuery();
						log.info("Se ejecuto consulta con exito.");
						while (resultset.next()) {
							usuario.setUsuarioId(resultset.getLong("USUARIO_ID"));
							usuario.setPersonaId(resultset.getLong("PERSONA_ID"));
							usuario.setClave(resultset.getString("CLAVE"));
							usuario.setFechaCreacion(resultset.getString("FECHA_CREACION"));
							usuario.setUsuarioCreador(resultset.getString("USUARIO_CREADOR"));
							usuario.setUsuario(resultset.getString("USUARIO"));
							usuario.setDni(resultset.getString("NRO_DOCUMENTO"));
							usuario.setNombres(resultset.getString("NOMBRES"));
							usuario.setApellidoPaterno(resultset.getString("AP_PATERNO"));
							usuario.setApellidoMaterno(resultset.getString("AP_MATERNO"));
							usuario.setEstadoRegistro(resultset.getString("ESTADO_REGISTRO"));
							usuario.setPerfilId(resultset.getLong("PERFIL_ID"));
							usuario.setIdEntidad(resultset.getLong("ENTIDAD_ID"));
							usuario.setEmail(resultset.getString("EMAIL_PERSONAL"));
						}
					} catch(SQLException e) {
						log.error("SQLException : " , e);
						throw e;
					} catch (Exception e) {
						log.error("Exception : " , e);
						throw e;
					} finally {
						Utilitario.cerrarResultset(resultset);
						Utilitario.cerrarPreparedStatement(preparedStatement);
					}
				}
			});
		} catch (Exception e) {
			String mensajeError = consumirProcedimientoDAOLocal.consultarMensaje(Constantes.CODIGO_MSJ_ERROR_DB);
			throw new DAOExcepcion(Constantes.CODIGO_MSJ_ERROR_DB, mensajeError);
		}
		return usuario;
	}
	
	@Override
	public Usuario obtenerUsuarioPorPersonaId(final long personaId) throws DAOExcepcion {
		Session session = entityManager.unwrap(Session.class);
		final Usuario usuario = new Usuario();
		try {
			session.doWork(new Work() {
				@Override
				public void execute(Connection connection) throws SQLException {
					ResultSet resultset = null;
					PreparedStatement preparedStatement = null;
					String sql = "SELECT * FROM VW_CONSULTA_USUARIOS WHERE PERSONA_ID = ?";
					try {
						preparedStatement = connection.prepareStatement(sql);
						preparedStatement.setLong(1, personaId);
						resultset =	preparedStatement.executeQuery();
						log.info("Se ejecuto consulta con exito.");
						while (resultset.next()) {
							usuario.setUsuarioId(resultset.getLong("USUARIO_ID"));
							usuario.setPersonaId(resultset.getLong("PERSONA_ID"));
							usuario.setClave(resultset.getString("CLAVE"));
							usuario.setFechaCreacion(resultset.getString("FECHA_CREACION"));
							usuario.setUsuarioCreador(resultset.getString("USUARIO_CREADOR"));
							usuario.setUsuario(resultset.getString("USUARIO"));
							usuario.setDni(resultset.getString("NRO_DOCUMENTO"));
							usuario.setNombres(resultset.getString("NOMBRES"));
							usuario.setApellidoPaterno(resultset.getString("AP_PATERNO"));
							usuario.setApellidoMaterno(resultset.getString("AP_MATERNO"));
							usuario.setEstadoRegistro(resultset.getString("ESTADO_REGISTRO"));
							usuario.setPerfilId(resultset.getLong("PERFIL_ID"));
							usuario.setIdEntidad(resultset.getLong("ENTIDAD_ID"));
							usuario.setEmail(resultset.getString("EMAIL_PERSONAL"));
						}
					} catch(SQLException e) {
						log.error("SQLException : " , e);
						throw e;
					} catch (Exception e) {
						log.error("Exception : " , e);
						throw e;
					} finally {
						Utilitario.cerrarResultset(resultset);
						Utilitario.cerrarPreparedStatement(preparedStatement);
					}
				}
			});
		} catch (Exception e) {
			String mensajeError = consumirProcedimientoDAOLocal.consultarMensaje(Constantes.CODIGO_MSJ_ERROR_DB);
			throw new DAOExcepcion(Constantes.CODIGO_MSJ_ERROR_DB, mensajeError);
		}
		return usuario;
	}
	
	@Override
	public Usuario obtenerUsuarioPorDocumento(final String nroDocumento) throws DAOExcepcion {
		Session session = entityManager.unwrap(Session.class);
		final Usuario usuario = new Usuario();
		try {
			session.doWork(new Work() {
				@Override
				public void execute(Connection connection) throws SQLException {
					ResultSet resultset = null;
					PreparedStatement preparedStatement = null;
					String sql = "SELECT * FROM VW_CONSULTA_USUARIOS WHERE NRO_DOCUMENTO = ?";
					try {
						preparedStatement = connection.prepareStatement(sql);
						preparedStatement.setString(1, nroDocumento);
						resultset =	preparedStatement.executeQuery();
						log.info("Se ejecuto consulta con exito.");
						while (resultset.next()) {
							usuario.setUsuarioId(resultset.getLong("USUARIO_ID"));
							usuario.setPersonaId(resultset.getLong("PERSONA_ID"));
							usuario.setClave(resultset.getString("CLAVE"));
							usuario.setFechaCreacion(resultset.getString("FECHA_CREACION"));
							usuario.setUsuarioCreador(resultset.getString("USUARIO_CREADOR"));
							usuario.setUsuario(resultset.getString("USUARIO"));
							usuario.setDni(resultset.getString("NRO_DOCUMENTO"));
							usuario.setNombres(resultset.getString("NOMBRES"));
							usuario.setApellidoPaterno(resultset.getString("AP_PATERNO"));
							usuario.setApellidoMaterno(resultset.getString("AP_MATERNO"));
							usuario.setEstadoRegistro(resultset.getString("ESTADO_REGISTRO"));
							usuario.setPerfilId(resultset.getLong("PERFIL_ID"));
							usuario.setIdEntidad(resultset.getLong("ENTIDAD_ID"));
							usuario.setEmail(resultset.getString("EMAIL_PERSONAL"));
						}
					} catch(SQLException e) {
						log.error("SQLException : " , e);
						throw e;
					} catch (Exception e) {
						log.error("Exception : " , e);
						throw e;
					} finally {
						Utilitario.cerrarResultset(resultset);
						Utilitario.cerrarPreparedStatement(preparedStatement);
					}
				}
			});
		} catch (Exception e) {
			String mensajeError = consumirProcedimientoDAOLocal.consultarMensaje(Constantes.CODIGO_MSJ_ERROR_DB);
			throw new DAOExcepcion(Constantes.CODIGO_MSJ_ERROR_DB, mensajeError);
		}
		return usuario;
	}
	
	@Override
	public MensajeRespuesta eliminarUsuario(final long usuarioId, final String usuarioModificador)  throws DAOExcepcion {   	
    	final MensajeRespuesta mensajeRespuesta = new MensajeRespuesta();
		try {
			Session session = entityManager.unwrap(Session.class);
			session.doWork(new Work() {
				@Override
				public void execute(Connection connection) throws SQLException {
					CallableStatement callableStatement = null;
					try {
						connection.setAutoCommit(false);
						callableStatement = connection.prepareCall(Constantes.SP_ELIMINA_USUARIO);
						callableStatement.setLong("E_USUARIO_ID", usuarioId);
						callableStatement.setString("E_USUARIO_MODIFICADOR", usuarioModificador);
						callableStatement.registerOutParameter("S_ID_ERROR",OracleTypes.INTEGER);
						callableStatement.registerOutParameter("S_DES_ERROR",OracleTypes.VARCHAR);
						callableStatement.registerOutParameter("S_DES_ERROR_INFO", OracleTypes.VARCHAR);
						callableStatement.execute();
						log.info("Se ejecuto exitosamente el SP.");
						int codigoError = callableStatement.getInt("S_ID_ERROR");
						String mensajeError = callableStatement.getString("S_DES_ERROR");
						String mensajeErrorInfo = callableStatement.getString("S_DES_ERROR_INFO");
						mensajeRespuesta.setCodigoError(String.valueOf(codigoError));
						mensajeRespuesta.setMensajeError(mensajeError);
						
						if (callableStatement.getInt("S_ID_ERROR") == 0) {
							log.info("Se elimino usuario con exito en BD.");
							connection.commit();
						} else {
							log.info("No se pudo eliminar el usuario en BD. " + mensajeErrorInfo);
							throw new SQLException();
						}
					
					} catch(SQLException e){
						log.error("SQLException : ", e);
						connection.rollback();
						throw e;
					} catch (Exception e) {
						log.error("Exception : ", e);
						connection.rollback();
						throw e;
					}finally {
						Utilitario.cerrarCallableStatement(callableStatement);
					}
				}
			});
		
		} catch (Exception e) {
			if (mensajeRespuesta.getCodigoError() == null) {
				String mensajeError = consumirProcedimientoDAOLocal.consultarMensaje(Constantes.CODIGO_MSJ_ERROR_DB);
				throw new DAOExcepcion(Constantes.CODIGO_MSJ_ERROR_DB, mensajeError);
			}
			throw new DAOExcepcion(mensajeRespuesta.getCodigoError(), mensajeRespuesta.getMensajeError());
		}	
			
		return mensajeRespuesta;
	}
	
}
